package com.kye.express.business.order.add_order;

import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.UserSession;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.order.OrderAddOrderBean;
import com.kye.model.bean.order.OrderAddresses;
import com.kye.model.bean.order.OrderContrabandBean;
import com.kye.model.bean.order.request.RequestAddOrder;
import com.kye.model.bean.order.request.RequestOrderAddresses;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.OrderDataSource;
import com.kye.model.gson_adapter.ApiException;

import java.util.Date;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;

public interface AddOrderContract {
    interface AddOrderView extends IView, LoadingView, ErrorView {
        void onAddress(OrderAddresses.Address addresses);

        void onSuccess(OrderAddOrderBean orderAddOrderBean);

        void onCheckedContraband(String msg, OrderContrabandBean bean);
    }

    class AddOrderPresenter extends BasePresenter<AddOrderView> {

        private OrderDataSource mOrderDataSource;

        @Override
        public void bind(AddOrderView view) {
            super.bind(view);
            mOrderDataSource = new OrderDataSource();
        }

        public void getAddress() {
            UserSession.getInstance()
                    .getUserForRx()
                    .firstOrError()
                    .flatMap(new Function<User, SingleSource<OpenApiResult<List<OrderAddresses>>>>() {
                        @Override
                        public SingleSource<OpenApiResult<List<OrderAddresses>>> apply(User user) throws Exception {
                            return mOrderDataSource.getAddresses(new RequestOrderAddresses(user.getPhone(), user.getCustomCode()));
                        }
                    })
                    .flatMapObservable(new Function<OpenApiResult<List<OrderAddresses>>, ObservableSource<OrderAddresses>>() {
                        @Override
                        public ObservableSource<OrderAddresses> apply(OpenApiResult<List<OrderAddresses>> openApiResult) throws Exception {
                            return Observable.fromIterable(openApiResult.getData());
                        }
                    })
                    .flatMapIterable(new Function<OrderAddresses, Iterable<OrderAddresses.Address>>() {
                        @Override
                        public Iterable<OrderAddresses.Address> apply(OrderAddresses orderAddresses) throws Exception {
                            return orderAddresses.getAddresses();
                        }
                    })
                    .filter(new Predicate<OrderAddresses.Address>() {
                        @Override
                        public boolean test(OrderAddresses.Address addresses) throws Exception {
                            return addresses.isDefault();
                        }
                    })
                    .firstOrError()
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            getView().onLoading();
                        }
                    })
                    .doAfterTerminate(new Action() {
                        @Override
                        public void run() throws Exception {
                            getView().onLoaded();
                        }
                    })
                    .subscribe(new Consumer<OrderAddresses.Address>() {
                        @Override
                        public void accept(OrderAddresses.Address addresses) throws Exception {
                            getView().onAddress(addresses);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            if (throwable instanceof ApiException) {
                                getView().onError(((ApiException) throwable).getOpenApiResult().getMsg());
                            } else {
                                getView().onError();
                            }
                        }
                    });
        }

        public void submit(OrderAddresses.Address address, String commodities, String totalNumber, String weight, String totalPoll, String size, boolean dangTianDa, Date date, String remark) {
            RequestAddOrder requestAddOrder = new RequestAddOrder();

            if (address.isDefault()) {
                requestAddOrder.setAddress(address.getDetailsAddress());
            } else {
                requestAddOrder.setTemporaryAddress(address.getDetailsAddress());
            }

            if (dangTianDa) {
                requestAddOrder.setServiceMode1("当天达");
            }

            requestAddOrder.setCompanyCode(address.getCompanyCode());
            requestAddOrder.setOrderMan(address.getContacePerson());
            requestAddOrder.setOrderCompany(address.getCompany());
            requestAddOrder.setTelephone(address.getPhoneNo());
            requestAddOrder.setGetTelphone(address.getTelphone());
            requestAddOrder.setCommodities(commodities);
            requestAddOrder.setTotalNumber(totalNumber);
            requestAddOrder.setWeight1(weight);
            requestAddOrder.setTotalPoll(totalPoll);
            requestAddOrder.setSize(size);
            requestAddOrder.setGoodTime(date);
            requestAddOrder.setRemark(remark);

            Single.zip(Single.just(requestAddOrder), UserSession.getInstance()
                    .getUserForRx()
                    .firstOrError(), new BiFunction<RequestAddOrder, User, RequestAddOrder>() {
                @Override
                public RequestAddOrder apply(RequestAddOrder requestAddOrder, User user) throws Exception {
                    requestAddOrder.setPhone(user.getPhone());
                    return requestAddOrder;
                }
            })
                    .flatMap(new Function<RequestAddOrder, SingleSource<OpenApiResult<OrderAddOrderBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<OrderAddOrderBean>> apply(RequestAddOrder requestAddOrder) throws Exception {
                            return mOrderDataSource.addOrder(requestAddOrder);
                        }
                    })
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<OrderAddOrderBean>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<OrderAddOrderBean> result, OrderAddOrderBean orderAddOrderBean) {
                            getView().onSuccess(orderAddOrderBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<OrderAddOrderBean> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        public void checkContraband(String goodsName) {
            mOrderDataSource.checkContraband(goodsName)
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<OrderContrabandBean>() {
                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<OrderContrabandBean> result, OrderContrabandBean orderContrabandBean) {

                        }

                        @Override
                        public void onApiError(OpenApiResult<OrderContrabandBean> result, int code, String msg) {
                            if (result.getData() == null || result.getData().getIsLegal() <= 1) return;

                            getView().onCheckedContraband(msg, result.getData());
                        }

                        @Override
                        public void onOtherError(Throwable e) {

                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }
    }
}
